

#include <iostream>
#include <functional>
#include <vector>
#include <memory>
#include <unordered_map>
#include <unistd.h>


using task_t = std::function<void()>;
using release_t = std::function<void()>;

class TimerTask
{
public:
    TimerTask(uint64_t id, uint32_t delay, const task_t& cb)
        : _id(id), _timeout(delay), _task_cb(cb), _canceled(false) {}

    void SetRelease(const release_t& cb)
    {
        _release = cb;
    }

    uint32_t GetDelayTime()
    {
        return _timeout;
    }

    void Cancel()
    {
        _canceled = true;
    }

    ~TimerTask()
    {
        if (!_canceled)
        {
            _task_cb();
        }
        _release();
    }

private:
    uint64_t _id;       // 定时器任务对象 ID
    uint32_t _timeout;  // 定时任务的超时时间
    task_t _task_cb;    // 定时器对象要执行的定时任务
    release_t _release; // 用于删除 TimerWheel 中保存的定时器对象信息
    bool _canceled;     // 任务是否被取消 
};



class TimerWheel
{
private:
    using weak_task = std::weak_ptr<TimerTask>;
    using ptr_task = std::shared_ptr<TimerTask>;

    void RemoveTimer(uint64_t id)
    {
        auto it = _timers.find(id);
        if (it != _timers.end())
        {
            _timers.erase(it);
        }
    }

public:
    TimerWheel()
        : _capacity(60), _tick(0), _wheel(_capacity) {}

    void TimerAdd(uint64_t id, uint32_t delay, const task_t& cb)
    {
        ptr_task newtask = std::make_shared<TimerTask>(id, delay, cb);
        newtask->SetRelease(std::bind(&TimerWheel::RemoveTimer, this, id));
        _timers[id] = weak_task(newtask);
        _wheel[(_tick + delay) % _capacity].push_back(newtask);
    }

    void TimerRefresh(uint64_t id)
    {
        auto it = _timers.find(id);
        if (it == _timers.end())
        {
            return;
        }
        ptr_task newtask = it->second.lock();
        int delay = newtask->GetDelayTime();
        _wheel[(_tick + delay) % _capacity].push_back(newtask);
    }

    void TimerCancel(uint64_t id)
    {
        auto it = _timers.find(id);
        if (it == _timers.end())
        {
            return;
        }
        ptr_task task = it->second.lock();
        if (task) task->Cancel();
    }

    void RunTimerTask()
    {
        // 每秒钟执行一次
        _tick = (_tick + 1) % _capacity;
        _wheel[_tick].clear();
    }

    ~TimerWheel()
    {}

private:
    int _tick;      // 当前秒针，走到哪执行哪的任务
    int _capacity;  // 时间轮盘最大空间，即延迟时间
    std::vector<std::vector<ptr_task>> _wheel;
    std::unordered_map<uint64_t, weak_task> _timers;
};


class Test
{
public:
    Test()
    {
        std::cout << "构造" << std::endl;
    }

    ~Test()
    {
        std::cout << "析构" << std::endl;
    }
};

void DelTest(Test* t)
{
    delete t;
}


int main()
{
    TimerWheel tw;
    Test* pt = new Test();

    tw.TimerAdd(888, 5, std::bind(DelTest, pt));
    for (int i = 0; i < 5; ++i)
    {
        tw.TimerRefresh(888);
        tw.RunTimerTask();
        std::cout << "刷新了一下定时任务，重新计时 5s" << std::endl;
        sleep(1);
    }
    tw.TimerCancel(888);
    while (true)
    {
        std::cout << "-----------------------" << std::endl;
        tw.RunTimerTask();
        sleep(1);
    }

    return 0;
}